package com.rla.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.rla.common.core.domain.R;
import com.rla.common.core.page.TableDataInfo;
import com.rla.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rla.common.utils.SecurityUtils;
import com.rla.common.utils.StringUtils;
import com.rla.domain.bo.EhsEverydayBloodGlucoseBo;
import com.rla.domain.vo.EhsEverydayBloodGlucoseVo;
import com.rla.service.IBaseHealthTargetRuleService;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.stereotype.Service;
import com.rla.domain.bo.EhsEverydayUricAcidBo;
import com.rla.domain.vo.EhsEverydayUricAcidVo;
import com.rla.domain.EhsEverydayUricAcid;
import com.rla.mapper.EhsEverydayUricAcidMapper;
import com.rla.service.IEhsEverydayUricAcidService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

/**
 * 日常记录-尿酸记录Service业务层处理
 *
 * @author rla
 * @date 2025-09-11
 */


@RequiredArgsConstructor
@Service
public class EhsEverydayUricAcidServiceImpl implements IEhsEverydayUricAcidService {

    private final EhsEverydayUricAcidMapper baseMapper;
    private final IBaseHealthTargetRuleService iBaseHealthTargetRuleService;
    /**
     * 查询日常记录-尿酸记录
     */
    @Override
    public EhsEverydayUricAcidVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询日常记录-尿酸记录列表
     */
    @Override
    public TableDataInfo<EhsEverydayUricAcidVo> queryPageList(EhsEverydayUricAcidBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EhsEverydayUricAcid> lqw = buildQueryWrapper(bo);
        Page<EhsEverydayUricAcidVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询日常记录-尿酸记录列表
     */
    @Override
    public List<EhsEverydayUricAcidVo> queryList(EhsEverydayUricAcidBo bo) {
        LambdaQueryWrapper<EhsEverydayUricAcid> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<EhsEverydayUricAcid> buildQueryWrapper(EhsEverydayUricAcidBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EhsEverydayUricAcid> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getUserId()), EhsEverydayUricAcid::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getMeasuredTime()), EhsEverydayUricAcid::getMeasuredTime, bo.getMeasuredTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUricAcid()), EhsEverydayUricAcid::getUricAcid, bo.getUricAcid());
        lqw.eq(StringUtils.isNotBlank(bo.getSourceType()), EhsEverydayUricAcid::getSourceType, bo.getSourceType());
        lqw.like(StringUtils.isNotBlank(bo.getSourceName()), EhsEverydayUricAcid::getSourceName, bo.getSourceName());
        lqw.eq(StringUtils.isNotBlank(bo.getIsLook()), EhsEverydayUricAcid::getIsLook, bo.getIsLook());
        lqw.eq(StringUtils.isNotBlank(bo.getDeviceCode()), EhsEverydayUricAcid::getDeviceCode, bo.getDeviceCode());
        lqw.eq(StringUtils.isNotBlank(bo.getBusinessId()), EhsEverydayUricAcid::getBusinessId, bo.getBusinessId());
        lqw.eq(StringUtils.isNotBlank(bo.getTag()), EhsEverydayUricAcid::getTag, bo.getTag());
        lqw.eq(StringUtils.isNotBlank(bo.getColor()), EhsEverydayUricAcid::getColor, bo.getColor());
        lqw.eq(bo.getFgcCreatedate() != null, EhsEverydayUricAcid::getFgcCreatedate, bo.getFgcCreatedate());
        lqw.eq(StringUtils.isNotBlank(bo.getFgcLastmodifier()), EhsEverydayUricAcid::getFgcLastmodifier, bo.getFgcLastmodifier());
        lqw.eq(bo.getFgcLastmodifydate() != null, EhsEverydayUricAcid::getFgcLastmodifydate, bo.getFgcLastmodifydate());
        lqw.eq(StringUtils.isNotBlank(bo.getFgcCreator()), EhsEverydayUricAcid::getFgcCreator, bo.getFgcCreator());
        lqw.orderByDesc(EhsEverydayUricAcid::getMeasuredTime);
        return lqw;
    }

    /**
     * 新增日常记录-尿酸记录
     */
    @Override
    public String insertByBo(EhsEverydayUricAcidBo bo) {
        bo.setUserId(SecurityUtils.getUserId().toString()); // 设置用户ID为当前登录用户的ID
        EhsEverydayUricAcid add = BeanUtil.toBean(bo, EhsEverydayUricAcid.class);
        validEntityBeforeSave(add);

        // 调用指标计算服务，计算尿酸指标（传入尿酸值）
        Map<String, Object> resultMap = iBaseHealthTargetRuleService.calculateIndicators("尿酸", bo.getMeasuredType(), Double.valueOf(bo.getUricAcid()));

        if(ObjectUtil.isNotEmpty(resultMap)){ // 如果计算结果不为空
            add.setTag(resultMap.get("tag").toString()); // 设置健康标签
            add.setColor(resultMap.get("color").toString()); // 设置颜色标识
        }

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return add.getId();
    }

    /**
     * 修改日常记录-尿酸记录
     */
    @Override
    public Boolean updateByBo(EhsEverydayUricAcidBo bo) {
        bo.setUserId(SecurityUtils.getUserId().toString());
        EhsEverydayUricAcid update = BeanUtil.toBean(bo, EhsEverydayUricAcid.class);
        validEntityBeforeSave(update);
        update.setCreateBy(SecurityUtils.getUserId().toString());
        update.setCreateTime(new Date());
        return baseMapper.updateById(update) > 0;






    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(EhsEverydayUricAcid entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除日常记录-尿酸记录
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 查询趋势对比列表
     */

    @Override
    public List<Map<String,Object>> queryTrendList(EhsEverydayUricAcidBo bo) {
        List<Map<String, Object>> list = new ArrayList<>();
//        DateUtil
        String startDate = bo.getStartDate()+" 00:00:00";
        String endDate = bo.getEndDate()+" 23:59:59";
        //趋势数据图表
        list = baseMapper.getTrendList(bo.getUserId(),startDate,endDate);
        return list;

    }

    @Override
    public Map<String, Object> statisticsExce(EhsEverydayUricAcidBo bo) {
        String startDate = bo.getStartDate()+" 00:00:00";
        String endDate = bo.getEndDate()+" 23:59:59";
        List<Map<String, Object>> maps = baseMapper.statisticsExce(bo.getUserId(), startDate, endDate);
        Map<String, Object> map1 = new HashMap<>();
        if(ObjectUtil.isNotEmpty(maps)){
            for (Map<String, Object> map : maps) {
                map1.put(map.get("tag").toString(), map.get("num").toString());
            }
        }
        return map1;
    }

    @Override
    public Map<String, Object> queryDateCompare(String id) {
        Map<String, Object> map1 = new HashMap<>();

        EhsEverydayUricAcidVo vo = baseMapper.selectVoById(id);
        String measuredTime = vo.getMeasuredTime();
        String uricAcid = vo.getUricAcid();
        Map<String, Object> map = baseMapper.queryDateCompare(measuredTime);

        //最近一次
        if(ObjectUtil.isNotEmpty(map)){
            String uricAcidNext = map.get("uricAcid").toString();
            BigDecimal subtract = new BigDecimal(uricAcid).subtract(new BigDecimal(uricAcidNext));
            map1.put("lastDiff", subtract);
            map1.put("lastDate", map.get("measuredTimeFormat").toString());
            if (subtract.compareTo(BigDecimal.ZERO) > 0){
                map1.put("lastFlag", "1");
            }else {
                map1.put("lastFlag", "0");
            }
        }else {
            map1.put("lastFlag", "0");
            map1.put("lastDiff", "-");
            map1.put("lastDate", "-");
        }

        //近10天
        DateTime parse = DateUtil.parse(measuredTime);
        String dateStr = DateUtil.offsetDay(parse, -10).toDateStr();
        Map<String, Object> mapTen = baseMapper.queryDateCompare(dateStr);
        if (ObjectUtil.isNotEmpty(mapTen)){
            String uricAcidTen = mapTen.get("uricAcid").toString();
            BigDecimal subtract = new BigDecimal(uricAcid).subtract(new BigDecimal(uricAcidTen));
            map1.put("tenDaysDiff", subtract);
            map1.put("tenDaysDate", mapTen.get("measuredTimeFormat").toString());
            String dateStr1 = measuredTime;
            Date date1 = DateUtil.parse(dateStr1);

            String dateStr2 = mapTen.get("measuredTime").toString();
            Date date2 = DateUtil.parse(dateStr2);

            long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
            map1.put("betweenDay", betweenDay);

            if (subtract.compareTo(BigDecimal.ZERO) > 0){
                map1.put("tenDaysFlag", "1");
            }else {
                map1.put("tenDaysFlag", "0");
            }
        }else {
            map1.put("tenDaysFlag", "0");
            map1.put("tenDaysDiff", "-");
            map1.put("tenDaysDate", "-");
            map1.put("betweenDay", "-");
        }


        return map1;
    }

    @Override
    public Map<String, Object> queryDateContrast(EhsEverydayUricAcidBo bo) {
        String flag = bo.getFlag();
        HashMap<String, Object> map1 = new HashMap<>();
        String changeStartDate = bo.getChangeStartDate();
        String changeEndDate = bo.getChangeEndDate();
        String compareStartDate = bo.getCompareStartDate();
        String compareEndDate = bo.getCompareEndDate();

        if (flag.equals("day")) {
            bo.setUserId(SecurityUtils.getUserId().toString());
            String endDate = changeStartDate + " 00:00:00";
            String startDate = changeStartDate + " 23:59:59";
            String endDate1 = compareStartDate + " 00:00:00";
            String startDate1 = compareStartDate + " 23:59:59";
            Map<String, Float> average = baseMapper.average(bo.getUserId(), startDate, endDate);
            Float num = average != null ? average.get("num") : 0.0f;
            Map<String, Float> average1 = baseMapper.average1(bo.getUserId(), startDate1, endDate1);
            Float num1 = average1 != null ? average1.get("num1") : 0.0f;
            BigDecimal bd = new BigDecimal(num - num1);
            bd = bd.setScale(1, RoundingMode.HALF_UP);
            Float result = bd.floatValue();
            Integer integer;
            if (result > 0) {
                integer = 1;
            } else {
                integer = 0;
            }
            map1.put("startValue", num);
            map1.put("endValue", num1);
            map1.put("difference", result);
            map1.put("randf", integer);
            return map1;
        } else {
            List<String> list2 = new ArrayList<String>();
           /* if (flag.equals("week")){
                list2.add("星期一");
                list2.add("星期二");
                list2.add("星期三");
                list2.add("星期四");
                list2.add("星期五");
                list2.add("星期六");
                list2.add("星期日");
            }else {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate start = LocalDate.parse(changeEndDate, formatter);
                LocalDate end = LocalDate.parse(changeStartDate, formatter);

                // 遍历日期范围
                LocalDate current = start;
                while (!current.isAfter(end)) {
                    list2.add(current.format(formatter));
                    current = current.plusDays(1);
                }

            }*/
            bo.setUserId(SecurityUtils.getUserId().toString());
            String endDate = changeEndDate ;
            String startDate = changeStartDate ;
            String endDate1 = compareEndDate + " 00:00:00";
            String startDate1 = compareStartDate + " 23:59:59";
           Map<String, Float> average = baseMapper.average(bo.getUserId(), startDate, endDate);
            Float num = average != null ? average.get("num") : 0.0f;
            Map<String, Float> average1 = baseMapper.average1(bo.getUserId(), startDate1, endDate1);
            Float num1 = average1 != null ? average1.get("num1") : 0.0f;
            List<Map<String, Object>> maps = baseMapper.averageWeekList(bo.getUserId(), startDate, endDate);
            List<Map<String, Object>> data =maps;
                    List<String> dayNameList = data.stream()
                            .map(map -> (String) map.get("day_name"))
                            .collect(Collectors.toList());
            List<Double> selectedAvgList = data.stream()
                    .map(map -> (Double) map.get("selectedAvg"))
                    .collect(Collectors.toList());
            List<Double> compareAvgList = data.stream()
                    .map(map -> (Double) map.get("compareAvg"))
                    .collect(Collectors.toList());
            BigDecimal bd = new BigDecimal(num - num1);
            bd = bd.setScale(1, RoundingMode.HALF_UP);
            Float result = bd.floatValue();
            Integer integer;
            if (result > 0) {
                integer = 1;
            } else {
                integer = 0;
            }
            map1.put("startValue", num);
            map1.put("endValue", num1);
            map1.put("difference", result);
            map1.put("randf", integer);
            map1.put("dataList", list2);
            map1.put("changeList", maps);

            return map1;
        }

    }

    @Override
    public Map<String, Object> healthReport(EhsEverydayUricAcidBo bo) {
        String startDate = bo.getStartDate()+" 00:00:00";
        String endDate = bo.getEndDate()+" 23:59:59";
        Map<String, Object> healthReportCountMap = baseMapper.healthReport(bo.getUserId(), startDate, endDate);
        Map<String, Object> map1 = new HashMap<>();
        List<Map<String, Object>> maps = baseMapper.getTagCountStatistics(bo.getUserId(), startDate, endDate);
        if(ObjectUtil.isNotEmpty(maps)){
            for (Map<String, Object> map : maps) {
                map1.put(map.get("tagName").toString(), map.get("tagCount").toString());
            }
        }
        map1.put("count",ObjectUtil.isNotEmpty(healthReportCountMap.get("num"))? healthReportCountMap.get("num"):0 );
        map1.put("minValue",ObjectUtil.isNotEmpty(healthReportCountMap.get("min_value"))? healthReportCountMap.get("min_value"):0 );
        map1.put("maxValue",ObjectUtil.isNotEmpty(healthReportCountMap.get("max_value"))? healthReportCountMap.get("max_value"):0 );
        map1.put("avgValue",ObjectUtil.isNotEmpty(healthReportCountMap.get("avg_value"))? healthReportCountMap.get("avg_value"):0 );
        return map1;
    }

}
